package cn.fuxi2022.auth.controller;

import cn.fuxi2022.auth.properties.WeChatOpenConstantProperties;
import cn.fuxi2022.auth.service.UserLoginByWeChatOpenService;
import cn.fuxi2022.auth.service.UserLoginService;
import cn.fuxi2022.core.exception.SmartGroupException;
import cn.fuxi2022.model.resp.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.HashMap;

@RestController
@RequestMapping("wxopenlogin")
@Slf4j
public class UserLoginByWeChatOpenController {

    @Autowired
    private UserLoginByWeChatOpenService userLoginByWeChatOpenService;

    @Autowired
    private UserLoginService userLoginService;

    /**
     * 给前端提供 微信扫码登录 相关配置
     *
     * @return 微信扫码登录的所需配置
     */
    @GetMapping("/getProperties")
    public R getLoginProperties() {
        // 1.获取appid
        String appId = WeChatOpenConstantProperties.APP_ID;
        // 2.网页应用目前仅填写snsapi_login即可
        String scope = WeChatOpenConstantProperties.SCOPE;
        // 3.重定向地址，需要进行UrlEncode
        String redirect_uri = WeChatOpenConstantProperties.REDIRECT_URL;
        // 4.用于保持请求和回调的状态（前端获取当前时间）
        return R.ok().data("appid", appId).data("scope", scope).data("redirect_uri", redirect_uri);
    }

    /**
     * 微信登录接口
     * 该接口供微信登录回调实现
     *
     * @param code     类似于手机验证码，随机唯一的值（提供该验证码获取登录的用户信息）
     * @param state    校验的验证码，要求前端携带当前时间作为验证码，需要在30秒内登录，否则服务器不承认（用于保持请求和回调的状态，授权请求后原样带回给第三方。）
     * @param response 用于重定向，将提示信息 或 用户的token返回
     * @return 携带参数重定向至页面
     */
    @GetMapping("/login")
    public R login(String code, String state, HttpServletResponse response) throws IOException {
        // 1.准备返回的参数
        String responseProp = "";

        // 2.获取state，先校验state，再判断当前业务
        // A.按照“-”进行字符串分割
        String[] codeSplit = state.split("-");
        // B.校验state的时间
        long currentTimeMillis = System.currentTimeMillis();
        // C.当前的state时间必须为：当前时间 - 微信登录时间 的时间差 必须在30秒内
        if ((currentTimeMillis - Long.parseLong(codeSplit[0]) > 1000 * 30)) {
            // D.当前时间不合法，返回错误信息
            responseProp = "msg=" + URLEncoder.encode("扫码超时，请重新进行扫码登录", "UTF-8");
        } else {

            // 3.根据code获取openid及其access_token
            HashMap<String, String> openIdAndAccess = userLoginByWeChatOpenService.getOpenIdAndAccess(code);
            // log.info(String.valueOf(openIdAndAccess));

            try {
                // 4.根据state进行业务判断
                switch (codeSplit[1]) {
                    case "login":
                        // 5.登录业务
                        try {
                            // 执行根据用户获取token方法
                            String token = userLoginService.loginByWeChat(openIdAndAccess.get("unionid"));
                            // 将获取到的token放置到参数中
                            responseProp = "token=" + token;
                            // 获取微信的用户信息
                            HashMap<String, String> userInfo = userLoginByWeChatOpenService.getUserInfo(openIdAndAccess.get("openid"), openIdAndAccess.get("access_token"));
                            // 更新用户信息
                            userLoginService.updateByWeChat(userInfo);
                        } catch (Exception exception) {
                            // 6.未注册就扫码执行的分支
                            if ("该用户还未注册，请联系管理员注册后再登录".equals(exception.getMessage())) {
                                // 执行注册业务，保存
                                HashMap<String, String> userInfo = userLoginByWeChatOpenService.getUserInfo(openIdAndAccess.get("openid"), openIdAndAccess.get("access_token"));
                                userInfo.putAll(openIdAndAccess);
                                userLoginService.registerByWeChat(userInfo);
                                responseProp = "msg=" + URLEncoder.encode("系统已经确认您的注册，请管理员进入管理界面，设置手机号与密码", "UTF-8");
                            } else {
                                responseProp = "msg=" + URLEncoder.encode(exception.getMessage(), "UTF-8");
                            }
                        }
                        break;
                    case "register":
                        // TODO 通过微信扫码注册业务
                        break;
                    default:
                        throw new SmartGroupException("非法的业务需求");
                }
            } catch (Exception e) {
                responseProp = "msg=" + URLEncoder.encode("二维码已经过期，请重新扫码", "UTF-8");
            }
        }
        // 重定向到首页，携带msg或token重定向
        if (WeChatOpenConstantProperties.SEND_REDIRECT.contains("?")) {
            // 存在，说明前端的地址携带了参数，直接进行参数拼接
            response.sendRedirect(WeChatOpenConstantProperties.SEND_REDIRECT + "&" + responseProp);
        } else {
            // 不存在，说明前端的地址没有携带了参数，添加问号，再进行拼接
            response.sendRedirect(WeChatOpenConstantProperties.SEND_REDIRECT + "?" + responseProp);
        }

        return R.ok();
    }
}
